# Maintainer: Martell Malone <martellmalone@gmail.com>
# Maintainer: Alexey Pavlov <alexpux@gmail.com>
# Contributor: Ray Donnelly <mingw.android@gmail.com>
# Contributor: Mateusz Mikuła <mati865@gmail.com>
# Contributor: wirx6 <wirx654@gmail.com>
# Contributor: Yuui Tanabe <yuuitanabe@163.com>
# Contributor: Oscar Fuentes <ofv@wanadoo.es>
# Contributor: Adrian Pop <adrian.pop@liu.se>

if [[ $MINGW_PACKAGE_PREFIX == *-clang-* ]]; then
  _clangprefix=1
fi
_realname=llvm
pkgbase=mingw-w64-${_realname}-15
pkgname=("${MINGW_PACKAGE_PREFIX}-${_realname}-15"
         "${MINGW_PACKAGE_PREFIX}-clang-15")
_version=15.0.7
_rc=""
_tag=llvmorg-${_version}${_rc}
pkgver=${_version}${_rc/-/}
pkgrel=1
pkgdesc="C language family frontend for LLVM (mingw-w64)"
arch=('any')
mingw_arch=('mingw32' 'mingw64' 'ucrt64' 'clang64' 'clang32' 'clangarm64')
url="https://llvm.org/"
license=("custom:Apache 2.0 with LLVM Exception")
makedepends=("${MINGW_PACKAGE_PREFIX}-cc"
             "${MINGW_PACKAGE_PREFIX}-cmake"
             "${MINGW_PACKAGE_PREFIX}-z3"
             "${MINGW_PACKAGE_PREFIX}-libffi"
             "${MINGW_PACKAGE_PREFIX}-ninja"
             "${MINGW_PACKAGE_PREFIX}-pkg-config"
             "${MINGW_PACKAGE_PREFIX}-python"
             "git"
             )
_url=https://github.com/llvm/llvm-project/releases/download/${_tag}
source=("${_url}/llvm-${pkgver}.src.tar.xz"{,.sig}
        "${_url}/clang-${pkgver}.src.tar.xz"{,.sig}
        "${_url}/cmake-${pkgver}.src.tar.xz"{,.sig}
        "0001-Fix-GetHostTriple-for-mingw-w64-in-msys.patch"
        "0002-Revert-CMake-try-creating-symlink-first-on-windows.patch"
        "0003-add-pthread-as-system-lib-for-mingw.patch"
        "0004-enable-emutls-for-mingw.patch"
        "0005-Fix-llvm-ar-fails-to-update-thin-archives.patch"
        "0006-Do-not-check-file-access-time.patch"
        "0011-List-memrchr-as-unavailable-on-Windows.patch"
        "0101-link-pthread-with-mingw.patch"
        "0102-Explicitly-set-the-EmulatedTLS-codegen-option.patch")
# Some patch notes :)
#0001-0099 -> llvm
#0101-0199 -> clang
sha256sums=('4ad8b2cc8003c86d0078d15d987d84e3a739f24aae9033865c027abae93ee7a4'
            'SKIP'
            'a6b673ef15377fb46062d164e8ddc4d05c348ff8968f015f7f4af03f51000067'
            'SKIP'
            '8986f29b634fdaa9862eedda78513969fe9788301c9f2d938f4c10a3e7a3e7ea'
            'SKIP'
            'eb03df53671df6627768141b3aaa76abe176a14e5e47911c97bec544387c4aff'
            '5754c357cfc17769e80d95b673d41b1e54616e2487e037d761a1ac8bb28a2849'
            '7f0c64cd87b61e894be632f180ae5291e1aa9f1d9d382608f659067eeeda7146'
            '3837bd707d3d99a742e874d5c59a1e7d5502811d6926319974c5d9db86020039'
            'f8f57954b049451c47eed5f1573550666f978a2e983165ad6ef59e2660077942'
            '0f20f7a2578378b08d10b9e8ed7a6524f3a3425c8d380c6ea36b872fbff75b4b'
            'cc6aeca56693070de910670f546d2ec50a056d5356540dbd7b5aa74ced45980b'
            '715cb8862753854b2d9256e0b70003e2d1f57083d83eaeaf5a095fc72b8a4e26'
            '72116b1ca0ade4cfe7ffb0f0c1b4a98fe387df28b5e9ceeb00785cbb7d0c1e54')
validpgpkeys=('B6C8F98282B944E3B0D5C2530FC3042E345AD05D'  # Hans Wennborg, Google.
              '474E22316ABF4785A88C6E8EA2C794A986419D8A'  # Tom Stellard
              'D574BD5D1D0E98895E3BF90044F2485E45D59042') # Tobias Hieta
noextract=(clang-${pkgver}.src.tar.xz)

apply_patch_with_msg() {
  for _patch in "$@"
  do
    msg2 "Applying ${_patch}"
    patch -Nbp1 -i "${srcdir}/${_patch}"
  done
}

prepare() {
  cd "${srcdir}"
  plain "Extracting clang-${pkgver}.src.tar.xz due to symlink(s) without pre-existing target(s)"
  tar -xJf ${srcdir}/clang-${pkgver}.src.tar.xz -C ${srcdir} || true

  # Rename Directories
  for pkg in llvm clang cmake; do
    mv ${pkg}-$pkgver.src ${pkg}
  done

  # Patch llvm
  cd "${srcdir}/llvm"
  apply_patch_with_msg \
    "0001-Fix-GetHostTriple-for-mingw-w64-in-msys.patch" \
    "0002-Revert-CMake-try-creating-symlink-first-on-windows.patch"

  if (( ! _clangprefix )); then
    apply_patch_with_msg \
      "0003-add-pthread-as-system-lib-for-mingw.patch" \
      "0004-enable-emutls-for-mingw.patch"
  fi

  apply_patch_with_msg \
    "0005-Fix-llvm-ar-fails-to-update-thin-archives.patch" \
    "0006-Do-not-check-file-access-time.patch" \
    "0011-List-memrchr-as-unavailable-on-Windows.patch"

  # Patch clang
  cd "${srcdir}/clang"

  if (( ! _clangprefix )); then
    apply_patch_with_msg \
      "0101-link-pthread-with-mingw.patch"
  fi
  apply_patch_with_msg \
    "0102-Explicitly-set-the-EmulatedTLS-codegen-option.patch"
}

build() {
  cd "${srcdir}"

  case "${CARCH}" in
    i?86|armv7)
      # lld needs all the address space it can get.
      LDFLAGS+=" -Wl,--large-address-aware"
      ;;
  esac

  local -a platform_config
  local -a common_cmake_args

  if check_option "debug" "y"; then
    common_cmake_args+=(-DCMAKE_BUILD_TYPE=Debug)
    VERBOSE="VERBOSE=1"
  else
    common_cmake_args+=(-DCMAKE_BUILD_TYPE=Release)
  fi
  common_cmake_args+=(-Wno-dev
    -DCMAKE_INSTALL_PREFIX=${MINGW_PREFIX}/opt/llvm-15
    -DCMAKE_SYSTEM_IGNORE_PATH=/usr/lib
    -DLLVM_HOST_TRIPLE="${CARCH}-w64-windows-gnu"
    -DPython3_EXECUTABLE=${MINGW_PREFIX}/bin/python.exe)

  # Include location of libffi headers in CPPFLAGS
  FFI_INCLUDE_DIR="$(pkg-config --cflags libffi)"
  FFI_INCLUDE_DIR=$(echo $FFI_INCLUDE_DIR | sed 's|-I||g')

  if (( _clangprefix )); then

    platform_config+=(-DCLANG_DEFAULT_RTLIB=compiler-rt
      -DCLANG_DEFAULT_UNWINDLIB=libunwind
      -DCLANG_DEFAULT_CXX_STDLIB=libc++
      -DLLVM_ENABLE_LIBCXX=ON
      -DCLANG_DEFAULT_LINKER=lld
      -DLLVM_ENABLE_LLD=ON)
  fi

  local _projects="clang"

  platform_config+=(-DLLVM_TARGETS_TO_BUILD="AArch64;X86")

  mkdir -p build-${MSYSTEM} && cd build-${MSYSTEM}

  MSYS2_ARG_CONV_EXCL="-DCMAKE_INSTALL_PREFIX=" \
  ${MINGW_PREFIX}/bin/cmake.exe \
    -GNinja \
    -DFFI_INCLUDE_DIR="${FFI_INCLUDE_DIR}" \
    -DLIBCLANG_BUILD_STATIC=ON \
    -DLLVM_BUILD_STATIC=ON \
    -DLLVM_ENABLE_ASSERTIONS=OFF \
    -DLLVM_ENABLE_FFI=ON \
    -DLLVM_ENABLE_PROJECTS="${_projects}" \
    -DLLVM_ENABLE_THREADS=ON \
    -DLLVM_ENABLE_RTTI=ON \
    -DLLVM_INCLUDE_EXAMPLES=OFF \
    -DLLVM_INCLUDE_BENCHMARKS=OFF \
    -DLLVM_INCLUDE_TESTS=ON \
    -DLLVM_INCLUDE_UTILS=ON \
    "${common_cmake_args[@]}" \
    "${platform_config[@]}" \
    ../llvm

  ${MINGW_PREFIX}/bin/cmake.exe --build .

  # Disable automatic installation of components that go into subpackages
  # -i.orig to check what has been removed in-case it starts dropping more than it should
  #
  sed -i.orig '/clang\/cmake_install.cmake/d' tools/cmake_install.cmake
}

package_clang-15() {
  pkgdesc="C language family frontend for LLVM (mingw-w64)"
  url="https://clang.llvm.org/"
  depends=("${MINGW_PACKAGE_PREFIX}-llvm-15"
           $( ((_clangprefix)) && echo \
             "${MINGW_PACKAGE_PREFIX}-compiler-rt" \
             "${MINGW_PACKAGE_PREFIX}-crt" \
             "${MINGW_PACKAGE_PREFIX}-headers" \
             "${MINGW_PACKAGE_PREFIX}-lld" \
             "${MINGW_PACKAGE_PREFIX}-winpthreads" \
             || echo "${MINGW_PACKAGE_PREFIX}-gcc"))

  cmake --install "${srcdir}/build-${MSYSTEM}/tools/clang" --prefix "${pkgdir}${MINGW_PREFIX}/opt/llvm-15"
}

package_llvm-15() {
  pkgdesc="Low Level Virtual Machine (mingw-w64)"
  depends=("${MINGW_PACKAGE_PREFIX}-gcc-libs")

  cd "${srcdir}"/llvm

  DESTDIR="${pkgdir}" cmake --install "${srcdir}/build-${MSYSTEM}"

  install -Dm644 "${srcdir}/llvm/LICENSE.TXT" "${pkgdir}${MINGW_PREFIX}/opt/llvm-15/share/licenses/llvm/LICENSE"

  # Install CMake stuff
  install -d "${pkgdir}"${MINGW_PREFIX}/opt/llvm-15/share/llvm/cmake/{modules,platforms}
  install -Dm644 "${srcdir}"/llvm/cmake/modules/*.cmake "${pkgdir}"${MINGW_PREFIX}/opt/llvm-15/share/llvm/cmake/modules/
  install -Dm644 "${srcdir}"/llvm/cmake/platforms/*.cmake "${pkgdir}"${MINGW_PREFIX}/opt/llvm-15/share/llvm/cmake/platforms/

  # fix cmake files.
  local PREFIX_WIN=$(cygpath -wm ${MINGW_PREFIX})
  sed -e "s|${PREFIX_WIN}|${MINGW_PREFIX}|g" -i ${pkgdir}/${MINGW_PREFIX}/opt/llvm-15/lib/cmake/llvm/LLVMExports.cmake
}

# template start; name=mingw-w64-splitpkg-wrappers; version=1.0;
# vim: set ft=bash :

# generate wrappers
for _name in "${pkgname[@]}"; do
  _short="package_${_name#${MINGW_PACKAGE_PREFIX}-}"
  _func="$(declare -f "${_short}")"
  eval "${_func/#${_short}/package_${_name}}"
done
# template end;
